import axios from "axios";
// 保存所有未完成的网络请求
const requests: Array<() => void> = [];
// 标记是否正在刷新新 token 中
let isRefreshing = false;

// 创建实例
const service = axios.create({
	baseURL: "/api",
	timeout: 10000
});

/**
 * 请示拦截
 */
service.interceptors.request.use(
	(config) => {
		// 请示头中添加 token 的传递
		const token = sessionStorage.getItem("token");
		if (token) {
			config.headers.Authorization = `Bearer ${token}`;
		}
		return config;
	},
	(error) => Promise.reject(error)
);

/**
 * 响应拦截
 */
service.interceptors.response.use(
	async (response) => {
		console.log("response");

		const { code, data, message } = response.data;
		// 响应状态码为 2xx，表示成功
		if (response.status >= 200 && response.status < 300) {
			// 获取后端响应数据
			// 判断后端响应数据的规范
			if (code === 200) {
				return data;
			}
		}

		// 其它问题，则进行全局错误提示
		const error = new Error(message || "响应拦截时出现异常问题");
		return Promise.reject(error);
	},
	async (error) => {
		const { code,message } = error.response.data;
		// 如果返回的 code 表示的是用户 token 异常的问题
		if (error.response.status === 401) {
			//长短 token 的解决方案(无感刷新 token)
			if (Number(code) === 4008) {
				// token 过期
				if (!isRefreshing) {
					// 标记刷新 token
					isRefreshing = true;
					// token 过期后，重新请求服务端刷新 token 的 API 接口
					// 以获取另一个在有效期内的新 token 进行使用
					const { token } = (
						await service.get("API", {
							headers: {
								Authorization: `Bearer ${sessionStorage.token}`
							}
						})
					).data as {
						token: string;
					};
					// 标记刷新 token 结束
					isRefreshing = false;
					// 将获取到的新 token 保存到本地
					sessionStorage.token = token;
					// 将之前未完成的网络请求重新发送完成
					service(error.response.config);
					requests.forEach((fn) => fn());
				} else {
					return new Promise((resolve) => {
						requests.push(() => {
							resolve(service(error.response.config));
						});
					});
				}
			} else {
				//通常前端会清除本地用户登录的状态信息，然后跳转到登录页面重新登录以获得正确的 token
			}
		}
		// 打印错误信息
		return Promise.reject(message);
	} // 出现异常，可进行全局错误提示
);

export default service;
